import { Injectable } from '@nestjs/common';
import {
  CouponProduct_Create_Dto,
  CouponProduct_FindAllByConponId_Dto,
  CouponProduct_Update_Dto,
} from './assets/couponProduct.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { CouponProduct } from './assets/couponProduct.entity';
import { In, Repository } from 'typeorm';
import { Product } from '../product/assets/product.entity';
import { Platform } from '../platform/assets/platform.entity';
import { Coupon } from '../coupon/assets/coupon.entity';
import { Class_HttpException_Base } from '@/common/classes/httpException';

@Injectable()
export class CouponProduct_Service {
  constructor(
    @InjectRepository(CouponProduct)
    private couponProduct_Repository: Repository<CouponProduct>,
    @InjectRepository(Product)
    private product_Repository: Repository<Product>,
    @InjectRepository(Platform)
    private platform_Repository: Repository<Platform>,
    @InjectRepository(Coupon)
    private coupon_Repository: Repository<Coupon>,
  ) {}
  async couponProduct_Create(body: CouponProduct_Create_Dto) {
    if (body.products.length == 0) return new Class_HttpException_Base('规格不能为空！');
    const couponProductsResult = (await this.couponProduct_Repository
      .createQueryBuilder('couponProduct')
      .leftJoin('couponProduct.product', 'product')
      .leftJoin('couponProduct.coupon', 'coupon')
      .leftJoin('couponProduct.platform', 'platform')
      .select(['product.id AS productId', 'product.productName AS productName'])
      .where('coupon.id = :coupoId', { coupoId: body.products[0].couponId })
      .andWhere('platform.id = :platformId', { platformId: body.products[0].platformId })
      .getRawMany()) as unknown as { productId: number; productName: string }[];
    const addProducts = [];
    const adddProducts = [];
    const hadProducts = [];
    body.products.map((product) => {
      const findResult = couponProductsResult.find((item) => {
        return item.productId == product.productId;
      });
      if (!findResult) {
        addProducts.push(product);
        if (adddProducts.length > 3) return;
        if (adddProducts.length == 3) return adddProducts.push('等');
        adddProducts.push(product.productId);
      } else {
        hadProducts.push(findResult.productName);
      }
    });
    const couponProducts = [];
    addProducts.forEach((item) => {
      couponProducts.push({
        product: this.product_Repository.create({ id: item.productId }),
        platform: this.platform_Repository.create({ id: item.platformId }),
        coupon: this.coupon_Repository.create({ id: item.couponId }),
      });
    });
    await this.couponProduct_Repository.save(couponProducts);
    const str = adddProducts.length == 0 ? '' : '规格id为' + adddProducts.join(',') + '的平台新增成功。';
    return {
      existed: hadProducts.length !== 0,
      message: hadProducts.length !== 0 ? str + hadProducts.join(',') + '已经存在' : '新增成功',
    };
  }
  async couponProduct_Update(body: CouponProduct_Update_Dto) {
    if (body.products.length == 0) return new Class_HttpException_Base('规格不能为空！');
    const couponProducts = await this.couponProduct_Repository
      .createQueryBuilder('couponProduct')
      .leftJoinAndSelect('couponProduct.product', 'product')
      .where('couponProduct.couponId = :couponId', { couponId: body.products[0].couponId })
      .andWhere('couponProduct.platformId = :platformId', { platformId: body.products[0].platformId })
      .getMany();
    const couponProductMap = new Map(couponProducts.map((p) => [p.product.id, p]));
    const productsInBodyNotInCoupon = body.products.filter(
      (product) => !couponProductMap.has(product.productId),
    );
    const bodyProductMap = new Map(body.products.map((p) => [p.productId, p]));
    const productsInCouponNotInBody = couponProducts.filter(
      (product) => !bodyProductMap.has(product.product.id),
    );
    if (productsInCouponNotInBody.length != 0) {
      const ids = [];
      productsInCouponNotInBody.map((item) => {
        ids.push(item.id);
      });
      await this.couponProduct_Repository.delete({ id: In(ids) });
    }
    const couponProductsSave = [];
    productsInBodyNotInCoupon.forEach((item) => {
      couponProductsSave.push({
        product: this.product_Repository.create({ id: item.productId }),
        platform: this.platform_Repository.create({ id: item.platformId }),
        coupon: this.coupon_Repository.create({ id: item.couponId }),
      });
    });
    await this.couponProduct_Repository.save(couponProductsSave);
    return '修改成功';
  }

  async couponProduct_Remove(couponId: string, platformId: string) {
    const result = await this.couponProduct_Repository
      .createQueryBuilder('couponProduct')
      .where('couponProduct.couponId = :couponId', { couponId })
      .andWhere('couponProduct.platformId = :platformId', { platformId })
      .getMany();
    if (result.length) return new Class_HttpException_Base('没有相关的优惠券对应平台的规格');
    await this.couponProduct_Repository
      .createQueryBuilder('couponProduct')
      .delete()
      .where('couponProduct.couponId = :couponId', { couponId })
      .andWhere('couponProduct.platformId = :platformId', { platformId })
      .execute();
    return '删除成功';
  }

  async couponProduct_Admin_FindAllByConponId(query: CouponProduct_FindAllByConponId_Dto) {
    const queryBuilder = this.couponProduct_Repository
      .createQueryBuilder('couponProduct')
      .leftJoin('couponProduct.product', 'product')
      .leftJoin('couponProduct.platform', 'platform')
      .select(['couponProduct.platformId AS platformId', 'platform.platFormName AS platFormName'])
      .addSelect(
        'JSON_ARRAYAGG(JSON_OBJECT("id", product.id, "productName", product.productName))',
        'products',
      )
      .groupBy('platformId')
      .where('couponId = :couponId', { couponId: query.couponId });
    const list = await queryBuilder
      .andWhere(query.platformId ? 'platform.id = :platformId' : '1=1', { platformId: query.platformId })
      .getRawMany();
    const totalElements = await queryBuilder
      .andWhere(query.platformId ? 'platform.id = :platformId' : '1=1', { platformId: query.platformId })
      .getCount();
    return { list, totalElements };
  }
}
